package club.monkeywood.transaction.user.service;

import club.monkeywood.transaction.user.dao.CustomerRepository;
import club.monkeywood.transaction.user.dao.PayInfoRepository;
import club.monkeywood.transaction.user.domain.Customer;
import club.monkeywood.transaction.user.domain.PayInfo;
import club.monkeywood.transaction.user.dto.OrderDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
public class CustomerService {

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private PayInfoRepository payInfoRepository;

    @Transactional
    @RabbitListener(queuesToDeclare = @Queue("order:pay"))
    public void handleOrderNew(OrderDTO orderDTO){
        log.info("Get new order for pay:{}", orderDTO);

        Customer customer = customerRepository.findById(orderDTO.getCustomerId()).orElse(null);

        PayInfo payInfo = payInfoRepository.findByOrderId(orderDTO.getId());
        if(payInfo!=null){
            log.warn("已支付, 重复信息:{}",orderDTO);
            orderDTO.setStatus("PAID");
            amqpTemplate.convertAndSend("order:ticket_move",orderDTO);
            return;
        }

        if(customer.getDeposit()<orderDTO.getAmount()){
            log.warn("余额不足");
            orderDTO.setStatus("NOT_ENOUGH_DEPOSIT");
            amqpTemplate.convertAndSend("order:ticket_error", orderDTO);
            return;
        }

        PayInfo newPayInfo = new PayInfo();
        newPayInfo.setOrderId(orderDTO.getId());
        newPayInfo.setAmount(orderDTO.getAmount());
        newPayInfo.setStatus("PAID");
        //注意：不要用save，jpa有缓存，不会立即触发更新操作
        //payInfoRepository.save(newPayInfo);
        //saveAndFlush：立即触发更新操作
        payInfoRepository.saveAndFlush(newPayInfo);

        //使用数据库锁，避免高并发时，少扣费
        customerRepository.charge(orderDTO.getCustomerId(),
                orderDTO.getAmount());

        orderDTO.setStatus("PAID");
        amqpTemplate.convertAndSend("order:ticket_move",orderDTO);
    }

}
